﻿using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using QBZ.Evaluation.Models;
using QBZ.Evaluation.Repositories.DataAccess;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
namespace QBZ.Evaluation.Repositories
{
    public class UserRepository
    {
        private dbEvaluationContext _db;
        public UserRepository(dbEvaluationContext db)
        {
            _db = db;
        }

        public int AddUser(UserModel user)
        {
            var _userModel = new TbUser
            {
                CreateBy = 1,
                CreateOn = DateTime.Now,
                Guid = Guid.NewGuid(),
                IsDelete = false,
                RoleChildId = 1,
                UserEmail = user.UserEmail,
                UserName = user.UserName,
                UserNick = user.UserNick,
                UserPassword = user.UserPassword,
                UserLevel = user.UserLevel
            };
            _db.TbUser.Add(_userModel);
            _db.SaveChanges();
            return _userModel.UserId;
        }

        public int AddOAuth(OAuthModel oAuth)
        {
            var _oAuth = new TbOAuth
            {
                OAuthWay = oAuth.OAuthWay,
                BirthDay = oAuth.BirthDay,
                City = oAuth.City,
                Country = oAuth.Country,
                CreateBy = 0,
                CreateOn = DateTime.Now,
                FigureUrl = oAuth.FigureUrl,
                Guid = Guid.NewGuid(),
                NickName = oAuth.NickName,
                OpenId = oAuth.OpenId,
                Province = oAuth.Province,
                Sex = oAuth.Sex,
                Token = oAuth.Token,
                UserId = oAuth.UserId,
            };
            _db.TbOAuth.Add(_oAuth);
            _db.SaveChanges();
            return _oAuth.OAuthId;
        }


        public UserModel FindUserByEmail(string email, string password)
        {
            return _db.TbUser
                .Where(_ => _.UserEmail == email && _.UserPassword == password && _.IsDelete == false)
                .Select(_ => new UserModel
                {
                    CreateBy = _.CreateBy,
                    CreateOn = _.CreateOn,
                    Guid = _.Guid,
                    IsDelete = _.IsDelete,
                    RoleChildId = _.RoleChildId,
                    TimeStamp = _.TimeStamp,
                    UpdateBy = _.UpdateBy,
                    UpdateOn = _.UpdateOn,
                    UserEmail = _.UserEmail,
                    UserId = _.UserId,
                    UserLevel = (UserLevel)_.UserLevel,
                    UserName = _.UserName,
                    UserNick = _.UserNick,
                    UserPassword = _.UserPassword,
                    UserPhone = _.UserPhone


                })
                .FirstOrDefault();
        }

        public UserModel FindUserByPhone(string phone, string password)
        {
            return _db.TbUser
                .Where(_ => _.UserPhone == phone && _.UserPassword == password && _.IsDelete == false)
                .Select(_ => new UserModel
                {
                    CreateBy = _.CreateBy,
                    CreateOn = _.CreateOn,
                    Guid = _.Guid,
                    IsDelete = _.IsDelete,
                    RoleChildId = _.RoleChildId,
                    TimeStamp = _.TimeStamp,
                    UpdateBy = _.UpdateBy,
                    UpdateOn = _.UpdateOn,
                    UserEmail = _.UserEmail,
                    UserId = _.UserId,
                    UserLevel = (UserLevel)_.UserLevel,
                    UserName = _.UserName,
                    UserNick = _.UserNick,
                    UserPassword = _.UserPassword,
                    UserPhone = _.UserPhone


                })
                .FirstOrDefault();
        }

        public int DeleteUser(int userId)
        {
            var oauth = _db.TbUser.Find(userId);
            oauth.IsDelete = true;
            return _db.SaveChanges();
        }

        public int MoveAuth(int userIdFrom, int userIdTo)
        {
            var oauth = _db.TbOAuth.Where(_ => _.UserId == userIdFrom).ToList();
            oauth.ForEach(_ => _.UserId = userIdTo);
            return _db.SaveChanges();
        }

        public UserBaseModel FindUserByUserId(int userId)
        {
            return _db.TbUser
                .Where(_ => _.UserId == userId && _.IsDelete == false)
                .Select(_ => new UserBaseModel
                {
                    RoleChildId = _.RoleChildId,
                    UserEmail = _.UserEmail,
                    UserId = _.UserId,
                    UserLevel = (UserLevel)_.UserLevel,
                    UserName = _.UserName,
                    UserNick = _.UserNick,
                    UserPhone = _.UserPhone
                })
                .FirstOrDefault();
        }

        public UserModel FindUserByUserId(int userId, bool withAllInfo)
        {
            return _db.TbUser
                .Where(_ => _.UserId == userId && _.IsDelete == false)
                .Select(_ => new UserModel
                {
                    CreateBy = _.CreateBy,
                    CreateOn = _.CreateOn,
                    Guid = _.Guid,
                    IsDelete = _.IsDelete,
                    RoleChildId = _.RoleChildId,
                    TimeStamp = _.TimeStamp,
                    UpdateBy = _.UpdateBy,
                    UpdateOn = _.UpdateOn,
                    UserEmail = _.UserEmail,
                    UserId = _.UserId,
                    UserLevel = (UserLevel)_.UserLevel,
                    UserName = _.UserName,
                    UserNick = _.UserNick,
                    UserPassword = _.UserPassword,
                    UserPhone = _.UserPhone


                })
                .FirstOrDefault();
        }

        public void SetUserLevel(UserBaseModel userModel)
        {
            var user = _db.TbUser.Where(_ => _.UserId == userModel.UserId).FirstOrDefault();
            if (user != null)
            {
                user.UserLevel = userModel.UserLevel;
                _db.SaveChanges();
            }
        }

        public void ResetPassword(int userId,string password = "123456")
        {
            var user = _db.TbUser.Where(_ => _.UserId == userId).FirstOrDefault();
            if (user != null)
            {
                user.UserPassword = password;
                _db.SaveChanges();
            }
        }

        public List<UserModel> GetAll()
        {
            return _db.TbUser.Select(_ => new UserModel
            {
                CreateBy = _.CreateBy,
                CreateOn = _.CreateOn,
                Guid = _.Guid,
                IsDelete = _.IsDelete,
                RoleChildId = _.RoleChildId,
                TimeStamp = _.TimeStamp,
                UpdateBy = _.UpdateBy,
                UpdateOn = _.UpdateOn,
                UserEmail = _.UserEmail,
                UserId = _.UserId,
                UserLevel = (UserLevel)_.UserLevel,
                UserName = _.UserName,
                UserNick = _.UserNick,
                UserPassword = _.UserPassword


            }).ToList();
        }
        public RowsModel getUsersInfo(JObject filter, string order, int skip = 0, int take = 15)
        {
            object userLevelFilter = null;
            int userIdFilter = 0;
            string userEmailFilter = null;
            string userNickFilter = null;
            string userPhoneFilter = null;
            string userNameFilter = null;
            string[] userRole = new string[] { };
            List<int?> userRoleFilter = new List<int?>() { };
            if (filter.ContainsKey("userLevel")) { Enum.TryParse(typeof(UserLevel), filter["userLevel"].ToString(), out userLevelFilter); }
            if (filter.ContainsKey("userId")) { int.TryParse(filter["userId"].ToString(), out userIdFilter); }
            if (filter.ContainsKey("userEmail")) { userEmailFilter = filter["userEmail"].ToString(); }
            if (filter.ContainsKey("userPhone")) { userPhoneFilter = filter["userPhone"].ToString(); }
            if (filter.ContainsKey("userNick")) { userNickFilter = filter["userNick"].ToString(); }
            if (filter.ContainsKey("userName")) { userNameFilter = filter["userName"].ToString(); }
            if (filter.ContainsKey("roleChildId"))
            {
                userRole = filter["roleChildId"].ToString().Split('-');
                foreach (var r in userRole)
                {
                    if (!string.IsNullOrWhiteSpace(r))
                    {
                        userRoleFilter.Add(int.Parse(r));
                    }
                }
            }

            var total = _db.TbUser
                            .Where(user =>
                             user.IsDelete == false
                             && (userRoleFilter.Count() == 0 || userRoleFilter.Contains(user.RoleChildId))
                             && (userLevelFilter == null || user.UserLevel == (UserLevel)userLevelFilter)
                             && (userEmailFilter == null || user.UserEmail.Contains(userEmailFilter))
                             && (userPhoneFilter == null || user.UserPhone.Contains(userPhoneFilter))
                             && (userNameFilter == null || user.UserName.Contains(userNameFilter))
                             && (userNickFilter == null || user.UserNick.Contains(userNickFilter))
                             && (userIdFilter == 0 || user.UserId == userIdFilter))
                           .Count();

            var rows = (from user in _db.TbUser
                            //join rc in _db.TbRoleChild on user.RoleId equals rc.RoleChildId
                            //join r in _db.TbRole on rc.RoleId equals r.RoleId
                        where
                            user.IsDelete == false
                            && (userRoleFilter.Count() == 0 || userRoleFilter.Contains(user.RoleChildId))
                            && (userLevelFilter == null || user.UserLevel == (UserLevel)userLevelFilter)
                            && (userEmailFilter == null || user.UserEmail.Contains(userEmailFilter))
                            && (userPhoneFilter == null || user.UserPhone.Contains(userPhoneFilter))
                            && (userNameFilter == null || user.UserName.Contains(userNameFilter))
                            && (userNickFilter == null || user.UserNick.Contains(userNickFilter))
                            && (userIdFilter == 0 || user.UserId == userIdFilter)
                        select new UserBaseModel
                        {
                            RoleChildId = user.RoleChildId,
                            //RoleChildName = rc.RoleChildName,
                            //RoleId = rc.RoleId??0,benlaijiuga
                            //RoleName = r.RoleName,
                            UserEmail = user.UserEmail,
                            UserId = user.UserId,
                            UserLevel = (UserLevel)user.UserLevel,
                            UserName = user.UserName,
                            UserNick = user.UserNick,
                            UserPhone = user.UserPhone
                        })
                        .OrderBy(order)
                        .Skip(skip)
                        .Take(take)
                        .ToList();
            return new RowsModel { total = total, rows = rows };

        }

        public OAuthModel FindOAuth(OAuthModel oAuthModel)
        {
            var _oAuth = _db.TbOAuth.Include("User").Where(_ => _.OAuthWay == oAuthModel.OAuthWay && ((oAuthModel.UnionId!=null && _.UnionId == oAuthModel.UnionId)||(_.OpenId == oAuthModel.OpenId))).FirstOrDefault();
            if(_oAuth != null)
            {
                oAuthModel.UserLevel = _oAuth.User.UserLevel;
                oAuthModel.UserId = _oAuth.UserId;
                _oAuth.BirthDay = oAuthModel.BirthDay;
                _oAuth.City = oAuthModel.City;
                _oAuth.Country = oAuthModel.Country;
                _oAuth.FigureUrl = oAuthModel.FigureUrl;
                _oAuth.NickName = oAuthModel.NickName;
                _oAuth.Province = oAuthModel.Province;
                _oAuth.Sex = oAuthModel.Sex;
                _oAuth.Token = oAuthModel.Token;
                _oAuth.Language = oAuthModel.Language;
                _db.SaveChanges();
            }
            return oAuthModel;
        }

        public bool CheckPermission(int userId, UserLevel level)
        {
            return _db.TbUser.Any(_ => _.UserId == userId && _.UserLevel >= level && _.IsDelete == false);

        }

    }
}
